
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author joaera,rco251, julicampagna, giseMontanari
 */
public class Polinomio {

    private ArrayList<Termino> terminos;

    public Polinomio(ArrayList<Integer> coef){
        int i = 0;
        terminos = new ArrayList<Termino>();
        while (i<coef.size()){
            Termino term = new Termino(coef.get(i),coef.size()-i-1);
            terminos.add(term);
            i++;
        }
    }

    public Polinomio(){
        terminos = new ArrayList<Termino>();
    }

    private Termino makeTermino(String str){
        int i = 0;
        String val = "";
        String exp = "";
        while (str.charAt(i) != ('\u0009')){
            val += str.charAt(i);
            i++;
        }
        i++;
        while (i<str.length()){
            exp += str.charAt(i);
            i++;
        }
        int v = Integer.parseInt(val);
        int e = Integer.parseInt(exp);
        Termino ter = new Termino(v,e);
        return ter;
    }
    
    public void makePolinomioFromFile(String filename){
        try {
            FileReader fr = new FileReader(filename);
            BufferedReader entrada = new BufferedReader(fr);
            String s;
            terminos.clear();
            while((s = entrada.readLine()) != null){
                terminos.add(makeTermino(s));
            }
            entrada.close();
        }
        catch(java.io.FileNotFoundException fnfex) {
             System.out.println("Archivo no encontrado");
        }
        catch(java.io.IOException ioex) {
            System.out.println("Error al cargar el archivo");
        }
    }

    public void verPolinomio(){
        String res = terminos.get(0).toString();
        Termino aux = new Termino();
        int i = 1;
        while (i<terminos.size()){
            aux = terminos.get(i);
            if (aux.getValor() >=0){
                res = res + " +" + aux.toString();
            }
            else{
                res = res + " " + aux.toString();
            }
            i++;
        }
        System.out.println(res);
    }

    public void addTermPolinomio(int v, int e) throws Exception{
        Termino ter = new Termino(v,e);
        if (perteneceGrado(ter.getExponente())){
            throw new Exception ("Ya se encontraba un termino con ese exponente");
        }
        terminos.add(ter);
    }


    protected void insertOrd(Termino term) {
        if (terminos.isEmpty()){
            terminos.add(term);
        }
        else {
            int central;
            int primero = 0;
            int ultimo = terminos.size()-1;
            while (primero <= ultimo){
                central = ((primero + ultimo)/2);
                if(term.getExponente() >= terminos.get(central).getExponente()){
                    ultimo = central - 1;
                }
                else{
                    primero = central + 1;
               }
            }
            terminos.add(primero, term);
        }
    }

    public int size(){
        return terminos.size();
    }


    public void ordenarDec(){
        Polinomio a = new Polinomio();
        int i = 0;
        while (i < terminos.size()){
            a.insertOrd(terminos.get(i));
            i++;
        }
        terminos = a.getTerminos();
    }

    public void completar() throws Exception{
        int g = grado() - 1;
        while (g>=0) {
            if (!perteneceGrado(g)){
                addTermPolinomio(0,g);
            }
            g--;
        }

    }

    public boolean estaOrdenado(){
        int i = 0;
        boolean res = true;
        while (i < terminos.size()-1 && res){
            if(terminos.get(i).getExponente() < terminos.get(i+1).getExponente()){
                res = false;
            }
            i++;
        }
        return res;
    }

    public int grado(){
        int i = 0;
        int res = 0;
        while (i < terminos.size()){
            if (terminos.get(i).getExponente() > res){
                res = terminos.get(i).getExponente();
            }
            i++;
        }
        return res;
    }

    public boolean perteneceGrado(int grado){
        int i = 0;
        while (i < terminos.size()){
            if (terminos.get(i).getExponente() == grado){
                return true;
            }
            i++;
        }
        return false;
    }

    public Termino get(int i){
        return terminos.get(i);
    }


    public int getValorDelExp(int e){
        int i = 0;
        while (i<size()){
            if (terminos.get(i).getExponente() == e){
                return terminos.get(i).getValor();
            }
            i++;
        }
        return 0;
    }

    public ArrayList<Integer> getCoeficientes() throws Exception{
        ordenarDec();
        completar();
        int i = 0;
        ArrayList<Integer> res = new ArrayList<Integer>();
        while (i<size()){
            res.add(get(i).getValor());
            i++;
        }
        return res;
    }

    /**
     * @return the terminos
     */
    public ArrayList<Termino> getTerminos() {
        return terminos;
    }

    /**
     * @param terminos the terminos to set
     */
    public void setTerminos(ArrayList<Termino> terminos) {
        this.terminos = terminos;
    }
}